﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

using log4net;
using CommonLib;
using ConfigUtilLib;




namespace QueueMgrUtil
{
    public enum QUEUE_WORK_ITEM_TYPE  {PROCESS_WORK_ITEM=0, PROCESS_END};
    

    public class QueueWorkItem
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private const string interfaceStr = "CommonLib.ProcessInterface"; 
        public QUEUE_WORK_ITEM_TYPE cmdType { get;private set;} 
        public Object ConfigRecord { get; private set; }
        public Object ResultRecord { get; private set; }
        private Guid  uniqueID;

        public QueueWorkItem(QUEUE_WORK_ITEM_TYPE workType, object ConfigRec, Object resultRec)
        {
            cmdType = workType;
            ConfigRecord = ConfigRec;
            ResultRecord = resultRec;
            uniqueID = Guid.NewGuid(); 
        }

        public bool ProcessRawData()
        {

            FetcherRecord fetchRec = ConfigRecord as FetcherRecord;
            if (fetchRec == null)
            {
                log.DebugFormat("Config Record Missing for QueueItem {0}", uniqueID.ToString());
                return false;
            }

            RawCrawledData rawData = ResultRecord as RawCrawledData;

            if (rawData == null)
            {
                log.DebugFormat("Raw Carwled Data  Record Missing for QueueItem {0}", uniqueID.ToString());
                return false;
            }

            // Super Cool Process Now .. 

            log.DebugFormat(" Processing Jobs for : {0}", fetchRec.FetcherName);

             // Loop thru Everey Process Object 
            foreach (ProcessorRecord processObject in fetchRec.ProcesserRecords)
            {
                Assembly reflectionAssembly = null;
                string asmFullPath = processObject.ProcessorDir + "\\" + processObject.AssemblyDllName;
                try
                {
                    // 1. Load Library 
                    reflectionAssembly = Assembly.LoadFrom(asmFullPath);
                }
                catch (Exception e)
                {
                    log.DebugFormat("Unable to Load DLL : {0} : {1}", asmFullPath,e.Message);
                    continue;
                }

                if (reflectionAssembly == null) continue;

                foreach (Type classType in reflectionAssembly.GetTypes())
                {

                    // 2. Verify Credentials  

                    if ((classType == null) || (classType.IsClass != true) || (classType.GetInterface(interfaceStr) == null))
                    {
                        continue;
                    }

                    // if all good Invoke The method 
                    ProcessInterface ibaseObject = Activator.CreateInstance(classType) as ProcessInterface;
                    log.DebugFormat("......Dynamically Invoking compute() on {0} Class of {1}", classType.FullName, uniqueID.ToString());

                    string configPath = processObject.ProcessorDir +"\\"+ processObject.ProcessConfigFile;
                    // Kick it off in a Thread.. 
                    ibaseObject.processrawData(rawData, configPath);
                    log.DebugFormat("Processing :  {0} @ ID  {1} ", fetchRec.FetcherName, uniqueID.ToString());

                }
            }
            return true;


        }

        
    }
}
